import { dateUtils, stringUtils } from 'my-ts-core';

import { Token } from './token';

/**
 * Access token is saved in memeory, NOT local storage | session stroage.
 * Refresh token should NEVER be saved. It MUST rely on HttpOnly cookie and handled by server side.
 */
export class TokenService {
  private static tokenField: Token | null;

  static get token(): Token | null {
    return this.tokenField;
  }

  /**
   * Check if the access token exists. True means exists. False means does NOT exist.
   */
  static get hasAccessToken(): boolean {
    return !stringUtils.isNullOrUndefinedOrEmptyString(this.token?.accessToken);
  }

  /**
   * Gets the active refresh token in string.
   */
  static get activeAccessToken(): string | undefined {
    return this.token?.accessToken;
  }

  /**
   * Gets current token bearer. It might be null.
   */
  static get bearer(): string | undefined {
    return this.token?.bearer;
  }

  /**
   * Checks if current access token is expired or not.
   * @returns True means access token is expired. False means access token is still active.
   */
  static get isAccessTokenExpired(): boolean {
    if (this.token != null) {
      // getCurrentDate() returns the local time.
      // The object retrieved from storage is UTC format.
      // Use new Date(this.token.localDateExpired) converts the UTC to local time.
      // That's why we need to create a new date instance for comparion.
      return this.token!.localDateExpired!.getTime() < dateUtils.getCurrentDate().getTime();
    }

    // If current token does NOT exists, it means need to refresh the token.
    // That's why we set as expired.
    return true;
  }

  /**
   * Saves the token based on the data from remote server.
   * @param token The data from remote server. It should contains below properties
   *                  string accessToken
   *                  string refreshToken
   *                  number expiresIn (seconds)
   *                  number requestConsumedSeconds (seconds)
   */
  static save(token: Token): void {
    this.tokenField = token;
  }

  /**
   * Removes the token from local storage and session storage.
   */
  static remove(): void {
    this.tokenField = null;
  }
}
